using System;
using System.Drawing;

using MonoTouch.CoreGraphics;
using MonoTouch.UIKit;

using OpenTK.Graphics.ES20;

namespace Storyteller.Framework.Graphics
{
	public class Texture : IDisposable
	{
		internal int TextureId { get { return textureId; } }

		public int Width { get; protected set; }
		public int Height { get; protected set; }

		protected Texture()
		{
		}

		unsafe public Texture(string fileName)
		{
			if (String.IsNullOrEmpty(fileName))
				throw new ArgumentException("fileName");

			var textureImage = UIImage.FromFile(fileName).CGImage;
		
			if(textureImage == null)
				throw new InvalidOperationException("Failed to load texture: " + fileName);
		
			var texWidth = textureImage.Width;
			var texHeight = textureImage.Height;
			var textureData = new byte[texWidth * texHeight * 4];
			fixed(byte* pTextureData = textureData)
			{
				using(CGBitmapContext textureContext = new CGBitmapContext((IntPtr) pTextureData,
					texWidth, texHeight, 8, texWidth * 4, textureImage.ColorSpace, CGImageAlphaInfo.PremultipliedLast))
				{
					textureContext.DrawImage(new RectangleF(0, 0, texWidth, texHeight), textureImage);
				}
			}
			
			textureId = 0;
			GL.GenTextures(1, ref textureId);
			GL.BindTexture(All.Texture2D, textureId);
			GL.TexImage2D(All.Texture2D, 0, (int)All.Rgba, texWidth, texHeight, 0, All.Rgba, All.UnsignedByte, textureData);
			textureData = null;
			GL.TexParameter(All.Texture2D, All.TextureMinFilter, (int)All.Linear);
			GL.TexParameter(All.Texture2D, All.TextureMagFilter, (int)All.Linear);
			GL.Enable(All.Texture2D);
			
			Width = texWidth;
			Height = texHeight;

		}

		public void Dispose()
		{
			Dispose(true);
			GC.SuppressFinalize(this);
		}

		protected virtual void Dispose(bool disposing)
		{
			if (!disposed)
			{
				if (disposing)
				{
					// dispose of managed resources
				}

				// dispose of unmanaged resources
				if (handleDisposing)
				{
					GL.DeleteTextures(1, ref textureId);
				}

				disposed = true;
			}
		}

		protected int textureId;

		bool disposed = false;
		protected bool handleDisposing = true;
	}
}
